﻿/*
 * test_com.cpp
 *
 *  Created on: 2016年12月18日
 *      Author: work
 */

#include <iostream>
#include <boost/program_options.hpp>

#include <dm/scada/devicemgr.hpp>
#include <dm/scada/statusmgr.hpp>
#include <dm/scada/discretemgr.hpp>
#include <dm/scada/measuremgr.hpp>
#include <dm/scada/cumulantmgr.hpp>
#include <dm/scada/actionmgr.hpp>

#include <dm/scada/rtvaluewatch.hpp>
#include <dm/scada/eventmonitor.hpp>
#include <dm/scada/timedmeasuremonitor.hpp>
#include <dm/scada/timedcumulantmonitor.hpp>

using namespace std;
using namespace boost::program_options;
using namespace dm::scada;

int main( int argc,char* argv[] ){
	options_description desc("DM实时数据监视工具");
	desc.add_options()
			("help,h","显示本帮助信息")
			("version,v","显示版本及编译信息")
			("set",value<int>(),"人工置数")
			("status,s",value<vector<int> >(),"状态量ID")
			("discrete,d",value<vector<int> >(),"离散量ID")
			("measure,m",value<vector<int> >(),"测量量ID")
			("cumulant,c",value<vector<int> >(),"累计量ID")
			("action,a",value<vector<int> >(),"动作ID。与set配合使用")
			;

	variables_map vm;
	try{
		store(parse_command_line(argc,argv,desc),vm);
		notify(vm);
	}catch( std::exception& ex ){
		cout << ex.what()<<endl;
		return 1;
	}

	if( vm.count("version") ){
		cout <<"V1.0 构建于 "<<__DATE__<<endl;
		return 1;
	}

	if( vm.count("help") ){
		cout <<desc<<endl;
		return 1;
	}

	if( vm.count("set") ){
		if( vm.count("status") ){
			vector<int> ids = vm["status"].as<vector<int> >();
			for( int i=0;i<(int)ids.size();++i ){
				index_t idx= CStatusMgr::ins().indexById(ids.at(i));
				if( idx<0 ){
					cout <<"不能找到状态量"<<ids.at(i)<<endl;
					return 0;
				}else{
					cout <<"状态量 "<<CStatusMgr::ins().deviceDesc(idx)<<' '<<CStatusMgr::ins().desc(idx)<<'('<<CStatusMgr::ins().name(idx)<<") id="<<ids.at(i)<<"置数"<<endl;
					CStatusMgr::ins().update(idx,CStatus(vm["set"].as<int>(),0),ByTest);
				}
			}
		}

		if( vm.count("discrete") ){
			vector<int> ids = vm["discrete"].as<vector<int> >();

			for( int i=0;i<(int)ids.size();++i ){
				index_t idx= CDiscreteMgr::ins().indexById(ids.at(i));
				if( idx<0 ){
					cout <<"不能找到离散量"<<ids.at(i)<<endl;
					return 0;
				}else{
					cout <<"离散量 "<<CDiscreteMgr::ins().deviceDesc(idx)<<' '<<CDiscreteMgr::ins().desc(idx)<<'('<<CDiscreteMgr::ins().name(idx)<<") id="<<ids.at(i)<<"置数"<<endl;
					CDiscreteMgr::ins().update(idx,CDiscrete(vm["set"].as<int>(),0),ByTest);
				}
			}
		}

		if( vm.count("measure") ){
			vector<int> ids = vm["measure"].as<vector<int> >();

			for( int i=0;i<(int)ids.size();++i ){
				index_t idx= CMeasureMgr::ins().indexById(ids.at(i));
				if( idx<0 ){
					cout <<"不能找到测量量"<<ids.at(i)<<endl;
					return 0;
				}else{
					cout <<"测量量 "<<CMeasureMgr::ins().deviceDesc(idx)<<' '<<CMeasureMgr::ins().desc(idx)<<'('<<CMeasureMgr::ins().name(idx)<<") id="<<ids.at(i)<<"置数"<<endl;
					CMeasureMgr::ins().update(idx,vm["set"].as<int>(),ByTest);
				}
			}
		}

		if( vm.count("cumulant") ){
			vector<int> ids = vm["cumulant"].as<vector<int> >();

			for( int i=0;i<(int)ids.size();++i ){
				index_t idx= CCumulantMgr::ins().indexById(ids.at(i));
				if( idx<0 ){
					cout <<"不能找到累计量"<<ids.at(i)<<endl;
					return 0;
				}else{
					cout <<"累计量 "<<CCumulantMgr::ins().deviceDesc(idx)<<' '<<CCumulantMgr::ins().desc(idx)<<'('<<CCumulantMgr::ins().name(idx)<<") id="<<ids.at(i)<<"置数"<<endl;
					CCumulantMgr::ins().update(idx,vm["set"].as<int>(),ByTest );
				}
			}
		}

		if( vm.count("action") ){
			vector<int> ids = vm["action"].as<vector<int> >();

			for( int i=0;i<(int)ids.size();++i ){
				index_t idx= CActionMgr::ins().indexById(ids.at(i));
				if( idx<0 ){
					cout <<"不能找到动作信息"<<ids.at(i)<<endl;
					return 0;
				}else{
					cout <<"动作信息 "<<CActionMgr::ins().deviceDesc(idx)<<' '<<CActionMgr::ins().desc(idx)<<'('<<CActionMgr::ins().name(idx)<<") id="<<ids.at(i)<<"置数"<<endl;
					CActionMgr::ins().update(idx,vm["set"].as<int>() );
				}
			}
		}

		return 0;
	}

	vector<TCRtValueWatch<CStatus>*> statuses;
	vector<TCRtValueWatch<CDiscrete>*> discretes;
	vector<TCRtValueWatch<CMeasure>*> measures;
	vector<TCRtValueWatch<CCumulant>*> cumulants;

	if( vm.count("status") ){
		vector<int> ids = vm["status"].as<vector<int> >();
		for( int i=0;i<(int)ids.size();++i ){
			index_t idx = CStatusMgr::ins().indexById(ids.at(i));
			if( idx<0 ){
				cout <<"不能找到状态量"<<ids.at(i)<<endl;
				return 0;
			}

			statuses.push_back( new TCRtValueWatch<CStatus>(CStatusMgr::ins().rt(idx)));
		}
	}

	if( vm.count("discrete") ){
		vector<int> ids = vm["discrete"].as<vector<int> >();
		for( int i=0;i<(int)ids.size();++i ){
			index_t idx = CDiscreteMgr::ins().indexById(ids.at(i));
			if( idx<0 ){
				cout <<"不能找到离散量量"<<ids.at(i)<<endl;
				return 0;
			}

			discretes.push_back( new TCRtValueWatch<CDiscrete>(CDiscreteMgr::ins().rt(idx)));
		}
	}

	if( vm.count("measure") ){
		vector<int> ids = vm["measure"].as<vector<int> >();
		for( int i=0;i<(int)ids.size();++i ){
			index_t idx = CMeasureMgr::ins().indexById(ids.at(i));
			if( idx<0 ){
				cout <<"不能找到模拟量"<<ids.at(i)<<endl;
				return 0;
			}

			measures.push_back( new TCRtValueWatch<CMeasure>(CMeasureMgr::ins().rt(idx)));
		}
	}

	if( vm.count("cumulant") ){
		vector<int> ids = vm["cumulant"].as<vector<int> >();
		for( int i=0;i<(int)ids.size();++i ){
			index_t idx = CCumulantMgr::ins().indexById(ids.at(i));
			if( idx<0 ){
				cout <<"不能找到累计量"<<ids.at(i)<<endl;
				return 0;
			}

			cumulants.push_back( new TCRtValueWatch<CCumulant>(CCumulantMgr::ins().rt(idx)));
		}
	}

	if( statuses.size()==0 && discretes.size()==0 && measures.size()==0 && cumulants.size()==0 ){
		cout <<"请指定需要监视的对象ID"<<endl;
		return 1;
	}

	bool firstTime = true;

	dm::scada::CDeviceMgr& devMgr = dm::scada::CDeviceMgr::ins();

	while(true){
		for( int i=0;i<(int)statuses.size();++i ){
			if( statuses[i]->refresh() || firstTime ){
				index_t idx = CStatusMgr::ins().indexOfRt(statuses[i]->getPointer());
				CStatus::value_t v = statuses[i]->getValue().getValue();
				cout	<<"状态量 "<<CStatusMgr::ins().id(idx)
						<<" "<<devMgr.desc(CStatusMgr::ins().deviceIndex(idx))<<'.'<<CStatusMgr::ins().desc(idx)
						<<" ->"<< int(v)
						<<"(" << CStatusMgr::ins().valueDesc(idx,v)
						<<") raw=" << int(statuses[i]->getValue().getRaw())
						<<endl;
			}
		}

		for( int i=0;i<(int)discretes.size();++i ){
			if( discretes[i]->refresh() || firstTime ){
				index_t idx = CDiscreteMgr::ins().indexOfRt(discretes[i]->getPointer());
				CDiscrete::value_t v = discretes[i]->getValue().getValue();
				cout	<<"离散量 "<< CDiscreteMgr::ins().id(idx)
						<<" " <<devMgr.desc(CDiscreteMgr::ins().deviceIndex(idx))<<'.'<< CDiscreteMgr::ins().desc(idx)
						<<" ->"<< int(v)
						<<"(" <<CDiscreteMgr::ins().valueDesc(idx,v)
						<<") raw="<< int(discretes[i]->getValue().getRaw())
						<<endl;
			}
		}

		for( int i=0;i<(int)measures.size();++i ){
			if( measures[i]->refresh() || firstTime ){
				index_t idx = CMeasureMgr::ins().indexOfRt(measures[i]->getPointer());
				cout	<<"测量量 "<<CMeasureMgr::ins().id(idx)
						<<" "<<devMgr.desc(CMeasureMgr::ins().deviceIndex(idx))<<'.'<<CMeasureMgr::ins().desc(idx)
						<<" ->"<<measures[i]->getValue().getValue()
						<<" "<<CMeasureMgr::ins().unit(idx)
						<<" raw="<<measures[i]->getValue().getRaw()
						<<endl;
			}
		}

		for( int i=0;i<(int)cumulants.size();++i ){
			if( cumulants[i]->refresh() || firstTime ){
				index_t idx = CCumulantMgr::ins().indexOfRt(cumulants[i]->getPointer());
				cout	<<"累计量 "<<CCumulantMgr::ins().id(idx)
						<<" "<<devMgr.desc(CCumulantMgr::ins().deviceIndex(idx))<<'.'<<CCumulantMgr::ins().desc(idx)
						<<" ->"<<cumulants[i]->getValue().getValue()
						<<" raw="<<cumulants[i]->getValue().getRaw()
						<<endl;
			}
		}

		if( firstTime )
			firstTime = false;
	}

	return 0;
}
